package com.scheduling.material.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.scheduling.material.dto.MaterialDTO;
import com.scheduling.material.dto.MaterialQueryDTO;
import com.scheduling.material.entity.Material;
import com.scheduling.material.mapper.MaterialMapper;
import com.scheduling.material.service.MaterialService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 原料业务层实现类
 *
 * @author 开发团队
 * @since 2025-05-29
 */
@Slf4j
@Service
public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> implements MaterialService {

    @Override
    public IPage<Material> getMaterialPage(MaterialQueryDTO queryDTO) {
        Page<Material> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        return baseMapper.selectMaterialPage(page, queryDTO);
    }

    @Override
    public Material getMaterialById(String materialId) {
        if (StrUtil.isBlank(materialId)) {
            throw new RuntimeException("原料ID不能为空");
        }
        return baseMapper.selectById(materialId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addMaterial(MaterialDTO materialDTO) {
        // 检查原料名称是否已存在
        if (checkMaterialNameExists(materialDTO.getMaterialName(), null)) {
            throw new RuntimeException("原料名称已存在");
        }

        Material material = new Material();
        BeanUtil.copyProperties(materialDTO, material);
        // ID由MyBatis-Plus自动生成，无需手动设置

        int result = baseMapper.insert(material);
        if (result > 0) {
            log.info("添加原料成功，原料ID：{}", material.getMaterialId());
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateMaterial(MaterialDTO materialDTO) {
        if (StrUtil.isBlank(materialDTO.getMaterialId())) {
            throw new RuntimeException("原料ID不能为空");
        }

        // 检查原料是否存在
        Material existMaterial = baseMapper.selectById(materialDTO.getMaterialId());
        if (existMaterial == null) {
            throw new RuntimeException("原料不存在");
        }

        // 检查原料名称是否已存在（排除当前原料）
        if (checkMaterialNameExists(materialDTO.getMaterialName(), materialDTO.getMaterialId())) {
            throw new RuntimeException("原料名称已存在");
        }

        Material material = new Material();
        BeanUtil.copyProperties(materialDTO, material);

        int result = baseMapper.updateById(material);
        if (result > 0) {
            log.info("更新原料成功，原料ID：{}", material.getMaterialId());
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteMaterial(String materialId) {
        if (StrUtil.isBlank(materialId)) {
            throw new RuntimeException("原料ID不能为空");
        }

        // 检查原料是否存在
        Material material = baseMapper.selectById(materialId);
        if (material == null) {
            throw new RuntimeException("原料不存在");
        }


        int result = baseMapper.deleteById(materialId);
        if (result > 0) {
            log.info("删除原料成功，原料ID：{}", materialId);
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteMaterials(List<String> materialIds) {
        if (materialIds == null || materialIds.isEmpty()) {
            throw new RuntimeException("原料ID列表不能为空");
        }

        for (String materialId : materialIds) {
            deleteMaterial(materialId);
        }
        return true;
    }

    @Override
    public List<Material> getAllMaterials() {
        LambdaQueryWrapper<Material> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(
                Material::getMaterialId,
                Material::getMaterialName,
                Material::getDescription,
                Material::getUnit,
                Material::getSafetyStock,
                Material::getCreateTime,
                Material::getUpdateTime
        );
        wrapper.orderByAsc(Material::getMaterialName);
        return baseMapper.selectList(wrapper);
    }

    @Override
    public boolean checkMaterialNameExists(String materialName, String excludeId) {
        if (StrUtil.isBlank(materialName)) {
            return false;
        }
        Integer count = baseMapper.checkMaterialNameExists(materialName, excludeId);
        return count != null && count > 0;
    }
} 